package IC.SemanticChecks;

import IC.Constants;
import IC.DataTypes;
import IC.AST.*;


/**
 *	a visitor class that is used to check if only a single legal main function exists.
 */
public class MainCheckingVisitor implements Visitor {

	private boolean MainMethodExist;
	
	//C'tor
	public MainCheckingVisitor(){
		this.MainMethodExist = false;
	}
	
	public Object visit(Program program) {
		for (ICClass c : program.getClasses()) 
			c.accept(this);
		if (MainMethodExist == false) 
			SemanticError.handle(SemanticErrorType.NO_MAIN, program.getLine());
		return null;
	}

	public Object visit(ICClass icClass) {
		for (Method m : icClass.getMethods())
			m.accept(this);
		return null;
	}

	public Object visit(StaticMethod method) {
		if ((method.getName().equals(Constants.MAIN_FUNCTION)) &&
			(method.getFormals().size() == 1) &&
			(method.getFormals().get(0).getType().getDimension() == 1) &&
			(method.getFormals().get(0).getType() instanceof PrimitiveType) &&
			(((PrimitiveType)method.getFormals().get(0).getType()).getDataType().equals(DataTypes.STRING))) {
			
				if (MainMethodExist == false) 
					MainMethodExist = true;
			    else 
			    	SemanticError.handle(SemanticErrorType.GTE_ONE_MAIN, method.getLine());
			
		}		
		return null;
	}
	
	public Object visit(VirtualMethod method) {
		return null;
	}
	
	public Object visit(Break breakStatement) {
		return null;
	}

	public Object visit(Continue continueStatement) {
		return null;
	}

	public Object visit(StatementsBlock statementsBlock) {
		return null;
	}
	
	public Object visit(If ifStatement) {
		return null;
	}
	
	public Object visit(Field field) {
		return null;
	}
	
	public Object visit(LibraryMethod method) {
		return null;
	}

	public Object visit(Formal formal) {
		return null;
	}

	public Object visit(PrimitiveType type) {
		return null;
	}

	public Object visit(UserType type) {
		return null;
	}

	public Object visit(Assignment assignment) {
		return null;
	}

	public Object visit(CallStatement callStatement) {
		return null;
	}

	public Object visit(Return returnStatement) {
		return null;
	}

	public Object visit(While whileStatement) {
		return null;
	}

	public Object visit(LocalVariable localVariable) {
		return null;
	}

	public Object visit(VariableLocation location) {
		return null;
	}

	public Object visit(ArrayLocation location) {
		return null;
	}

	public Object visit(StaticCall call) {
		return null;
	}

	public Object visit(VirtualCall call) {
		return null;
	}

	public Object visit(This thisExpression) {
		return null;
	}

	public Object visit(NewClass newClass) {
		return null;
	}

	public Object visit(NewArray newArray) {
		return null;
	}

	public Object visit(Length length) {
		return null;
	}

	public Object visit(MathBinaryOp binaryOp) {
		return null;
	}

	public Object visit(LogicalBinaryOp binaryOp) {
		return null;
	}

	public Object visit(MathUnaryOp unaryOp) {
		return null;
	}

	public Object visit(LogicalUnaryOp unaryOp) {
		return null;
	}

	public Object visit(Literal literal) {
		return null;
	}

	public Object visit(ExpressionBlock expressionBlock) {
		return null;
	}
	
}
